package com.devunion.bogdan.view.project.dialogs;

import com.devunion.bogdan.model.project.PaperType;
import com.devunion.bogdan.model.project.PaperInfo;
import com.devunion.bogdan.model.project.Author;
import com.devunion.bogdan.view.util.i18n;
import com.devunion.bogdan.view.util.DialogHelper;
import com.devunion.bogdan.view.util.ComponentFactory;
import com.toedter.calendar.JDateChooser;
import com.controls4j.components.text.JIntegerField;
import com.controls4j.components.text.IntegerDocument;
import com.controls4j.components.JInputValidator;
import com.controls4j.components.BasicValidationResult;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;

/**
 * @author Viktar Liaskovich
 */
public class PaperDialog extends JDialog {
    private PaperDialogAction dialogAction;
    private PaperType paperType;

    private PaperInfo paperInfo;

    private JTextField jTextFieldTitle;
    private JTextField jTextFieldAuthorFirstName;
    private JTextField jTextFieldAuthorLastName;

    private JCheckBox jCheckBoxExactDate;
    private JDateChooser jDateChooserExactDate;
    private JDateChooser jDateChooserStart;
    private JDateChooser jDateChooserEnd;

    private JComboBox jComboBoxLanguage;
    private JIntegerField jIntegerFieldPages;
    private JInputValidator jInputValidatorTitle;

    public PaperDialog(Frame owner, PaperDialogAction dialogAction, PaperType paperType) {
        this(owner, dialogAction, paperType, null);
    }

    public PaperDialog(Frame owner, PaperDialogAction dialogAction, PaperType paperType, PaperInfo paperInfo) {
        super(owner, true);
        this.dialogAction = dialogAction;
        this.paperInfo = paperInfo;
        this.paperType = paperType;

        getContentPane().setLayout(new GridBagLayout());
        setTitle(createTitle());

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowActivated(WindowEvent e) {
                jTextFieldTitle.grabFocus();
            }
        });

        initComponents();

        setSize(new Dimension(320, 470));
        setResizable(false);
        setLocationRelativeTo(null);
    }

    private void initComponents() {
        jTextFieldTitle = new JTextField();
        jTextFieldAuthorFirstName = new JTextField();
        jTextFieldAuthorLastName = new JTextField();

        jDateChooserExactDate = new JDateChooser();
        jDateChooserStart = new JDateChooser();
        jDateChooserEnd = new JDateChooser();

        jIntegerFieldPages = new JIntegerField(new IntegerDocument(0, 9999), 4);
        jInputValidatorTitle = new JInputValidator();
        jInputValidatorTitle.register(jTextFieldTitle);

        // TODO: move languages string to property file
        jComboBoxLanguage = new JComboBox(new String[]{"EN", "FR", "DE"});

        DialogHelper.placeComponent(getContentPane(), new JLabel(i18n.getString("Title")),
                0, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
                20, 10, 10, 10);

        DialogHelper.placeComponent(getContentPane(), jTextFieldTitle,
                1, 0, 1, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                20, 10, 10, 10);

        DialogHelper.placeComponent(getContentPane(), jInputValidatorTitle,
                2, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                20, 0, 10, 10);

        DialogHelper.placeComponent(getContentPane(), createAuthorPanel(),
                0, 1, 3, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                10, 10, 10, 10);

        DialogHelper.placeComponent(getContentPane(), createDatePanel(),
                0, 2, 3, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                10, 10, 10, 10);

        DialogHelper.placeComponent(getContentPane(), createLanguageAndPagesPanel(),
                0, 3, 3, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                10, 10, 10, 10);

        DialogHelper.placeComponent(getContentPane(), ComponentFactory.getHR(),
                0, 4, 3, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                0, 10, 10, 0);

        ComponentFactory.OkCancelPanel okCancelPanel = ComponentFactory.createPanelButtonOkCancel(this, new ComponentFactory.ActionHandler() {
            public void execute() {

                if (!checkDates()) {
                    return;
                }

                createPaperInfo();
                setVisible(false);
            }

            private boolean checkDates() {
                if (!jCheckBoxExactDate.isSelected()) {
                    Date start = jDateChooserStart.getDate();
                    Date end = jDateChooserEnd.getDate();

                    if (start.compareTo(end) > 0) {
                        JOptionPane.showMessageDialog(PaperDialog.this, "The second date need to be newer that first date", "Warning", JOptionPane.WARNING_MESSAGE);
                        return false;
                    }
                }

                return true;
            }
        }, new ComponentFactory.ActionValidator() {
            public boolean validate() {
                BasicValidationResult isValidTitle = (BasicValidationResult) jInputValidatorTitle.getValidatorModel().getContentValidator().validate(jTextFieldTitle.getText());
                return isValidTitle == BasicValidationResult.ACCEPTED;
            }
        });

        DialogHelper.placeComponent(getContentPane(), Box.createVerticalGlue(),
                0, 5, 3, 1,
                1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                0, 0, 0, 0);

        DialogHelper.placeComponent(getContentPane(), okCancelPanel,
                1, 6, 3, 1,
                0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE,
                10, 10, 10, 10);
    }

    private Component createLanguageAndPagesPanel() {
        JPanel result = new JPanel(new GridBagLayout());

        DialogHelper.placeComponent(result, new JLabel(i18n.getString("Language")),
                0, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
                0, 0, 10, 0);

        DialogHelper.placeComponent(result, jComboBoxLanguage,
                1, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                0, 0, 10, 0);

        DialogHelper.placeComponent(result, Box.createHorizontalGlue(),
                2, 0, 1, 1,
                1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
                0, 0, 0, 0);

        DialogHelper.placeComponent(result, new JLabel(i18n.getString("NumOfPages")),
                3, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE,
                0, 0, 10, 0);

        DialogHelper.placeComponent(result, jIntegerFieldPages,
                4, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL,
                0, 0, 0, 0);

        return result;
    }

    private void createPaperInfo() {
        paperInfo = new PaperInfo();
        paperInfo.setAuthor(new Author(jTextFieldAuthorFirstName.getText(), jTextFieldAuthorLastName.getText()));
        paperInfo.setType(paperType);

        paperInfo.setTitle(jTextFieldTitle.getText());

        if (jCheckBoxExactDate.isSelected()) {
            paperInfo.setCreationExactDate(jDateChooserExactDate.getDate());
        } else {
            paperInfo.setCreationStartDate(jDateChooserStart.getDate());
            paperInfo.setCreationEndDate(jDateChooserEnd.getDate());
        }

        paperInfo.setLanguage(jComboBoxLanguage.getSelectedItem().toString());
        paperInfo.setNumberOfPages(Integer.valueOf(jIntegerFieldPages.getText()));
    }

    private Component createDatePanel() {
        JPanel result = new JPanel(new GridBagLayout());
        result.setBorder(new TitledBorder(LineBorder.createBlackLineBorder(), i18n.getString("Date")));

        final JPanel jPanelDateRange = createDateRangePanel();

        jCheckBoxExactDate = new JCheckBox(i18n.getString("ExactDate"), true);

        if (jCheckBoxExactDate.isSelected()) {
            jPanelDateRange.setVisible(false);
        }

        jCheckBoxExactDate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                boolean isSelected = ((JCheckBox) e.getSource()).isSelected();

                jPanelDateRange.setVisible(!isSelected);
                jDateChooserExactDate.setVisible(isSelected);
            }
        });

        DialogHelper.placeComponent(result, jCheckBoxExactDate,
                0, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
                10, 10, 10, 10);

        DialogHelper.placeComponent(result, jDateChooserExactDate,
                0, 1, 1, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                10, 10, 10, 10);

        DialogHelper.placeComponent(result, jPanelDateRange,
                0, 1, 2, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                10, 10, 10, 10);

        return result;
    }

    private JPanel createDateRangePanel() {
        JPanel jPanelDateRange = new JPanel(new GridBagLayout());

        DialogHelper.placeComponent(jPanelDateRange, new JLabel(i18n.getString("StartDate")),
                0, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                0, 0, 10, 10);

        DialogHelper.placeComponent(jPanelDateRange, jDateChooserStart,
                0, 1, 1, 1,
                0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
                0, 0, 10, 0);

        DialogHelper.placeComponent(jPanelDateRange, Box.createHorizontalGlue(),
                1, 0, 1, 2,
                1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
                0, 0, 0, 0);

        DialogHelper.placeComponent(jPanelDateRange, new JLabel(i18n.getString("EndDate")),
                2, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                0, 0, 0, 10);

        DialogHelper.placeComponent(jPanelDateRange, jDateChooserEnd,
                2, 1, 1, 1,
                0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
                0, 0, 0, 0);

        return jPanelDateRange;
    }

    private Component createAuthorPanel() {
        JPanel result = new JPanel(new GridBagLayout());
        result.setBorder(new TitledBorder(LineBorder.createBlackLineBorder(), i18n.getString("Author")));

        DialogHelper.placeComponent(result, new JLabel(i18n.getString("FirstName")),
                0, 0, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
                10, 10, 10, 10);

        DialogHelper.placeComponent(result, jTextFieldAuthorFirstName,
                1, 0, 1, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                10, 10, 10, 10);

        DialogHelper.placeComponent(result, new JLabel(i18n.getString("LastName")),
                0, 1, 1, 1,
                0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
                10, 10, 10, 10);

        DialogHelper.placeComponent(result, jTextFieldAuthorLastName,
                1, 1, 1, 1,
                1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                10, 10, 10, 10);

        return result;
    }

    private String createTitle() {
        StringBuilder result = new StringBuilder();

        if (dialogAction == PaperDialogAction.ADD) {
            result.append(i18n.getString("AddNew"));
        } else {
            result.append(i18n.getString("Edit"));
        }

        result.append(" ");

        result.append(paperType.toString().toLowerCase());

        return result.toString();
    }

    public PaperInfo getPaperInfo() {
        return paperInfo;
    }

    public void setPaperInfo(PaperInfo paperInfo) {
        this.paperInfo = paperInfo;
    }
}
